use std::alloc::{alloc, dealloc, Layout};

use raw_perdata::RawPerdata;

struct TestPerdata {
    val: usize,
    perdata: RawPerdata<u64>,
}

fn alloc_perdata(size: usize) -> usize {
    let layout = Layout::from_size_align(size, 8).unwrap();
    unsafe {
        let ptr = alloc(layout);
        if ptr.is_null() {
            panic!("alloc fail");
        }
        ptr as usize
    }
}

fn free_perdata(size: usize) {
    let layout = Layout::from_size_align(size, 8).unwrap();
    unsafe {
        dealloc(size as *mut u8, layout);
    }
}

#[test]
fn perdata() {
    let mut perdata = TestPerdata {
        val: 3,
        perdata: RawPerdata::new(0, 5, alloc_perdata, free_perdata),
    };

    assert_eq!(perdata.val, 3);
    assert_eq!(*perdata.perdata.get(0), 0);
    *perdata.perdata.get_mut(0) = 4;
    *perdata.perdata.get_mut(1) = 3;
    *perdata.perdata.get_mut(4) = 1;
    assert_eq!(*perdata.perdata.get(0), 4);
    assert_eq!(*perdata.perdata.get(1), 3);
    assert_eq!(*perdata.perdata.get(2), 0);
    assert_eq!(*perdata.perdata.get(3), 0);
    assert_eq!(*perdata.perdata.get(4), 1);
    assert_eq!(perdata.val, 3);
    assert_eq!(*perdata.perdata.get(0), 4);
    assert_eq!(*perdata.perdata.get(1), 3);
    assert_eq!(*perdata.perdata.get(2), 0);
    assert_eq!(*perdata.perdata.get(3), 0);
    assert_eq!(*perdata.perdata.get(4), 1);
}
